#ifndef __threadhpp__
#define __threadhpp__
#include <iostream>
#include <string>
#include <unistd.h>
#include <pthread.h>
#include <functional>
#include "log.hpp"
#include <string.h>
#include <stdlib.h>
using namespace std;
using namespace LogModule;
#endif
namespace Threadmodule
{
    class Thread
    {
        using func_t = function<void()>;
    private:
        pthread_t _tid;
        string _name;
        bool _isdetached;
        bool _isrunning;
        void *_res;
        func_t _func;

    public:
        Thread(func_t func) : _tid(0),
                              _isdetached(false),
                              _isrunning(false),
                              _res(nullptr),
                              _func(func)
        {
            _name = "Thread-" + to_string(pthread_self());
        }
        pthread_t getid()
        {
            return _tid;
        }
        void detach()
        {
            if (_isrunning && _isdetached == false)
                pthread_detach(_tid);
            _isdetached = true;
        }
        static void *routine(void *args) // 为什么使用static：因为没有static的成员函数是默认带有this指针参数的，那么就会不符合pthread_created函数对routine函数参数的要求。但是如果使用了static修饰，那么就没有this指针参数，也就无法再调用成员变量_func函数，所以这里讲this指针传到了args中。
        {
            Thread *self = (Thread*)args;
            self->_func(); // 回调函数_func
            return nullptr;
        }
        bool start()
        {
            if (_isrunning == false)
            {
                int n = pthread_create(&_tid, nullptr, routine, this);
                if (n != 0)
                {
                    cerr << "create thread error:" << strerror(n) << endl;
                    return false;
                }
                if (_isdetached)
                    pthread_detach(_tid);
                _isrunning = true;
                return true;
            }
            else
                return false;
        }
        bool stop()
        {
            if (_isrunning == false)
                return false;
            int n = pthread_cancel(_tid);
            if (n != 0)
            {
                cerr << "stop thread error: " << strerror(n) << endl;
                return false;
            }
            _isrunning = false;
            return true;
        }
        void join()
        {
            if (_isdetached)
                return;
            int n = pthread_join(_tid, &_res);
            if (n != 0)
                cerr << "join thread error: " << strerror(n) << endl;
            else
                LOG(Loglevel::DEBUG)<<"join线程成功"<<"\r\n";
        }
        string getname()
        {
            return _name;
        }
        ~Thread()
        {
        }
    };
}